package cn.topevery.garden.dal.logic;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.topevery.garden.dal.constant.StringConstant;
import cn.topevery.garden.dal.dao.ProjPaymentDao;
import cn.topevery.garden.entity.dto.ProjMoneyDTO;
import cn.topevery.garden.entity.dto.ProjPaymentCudDTO;
import cn.topevery.garden.entity.dto.ProjPaymentDTO;
import cn.topevery.garden.entity.po.*;
import cn.topevery.garden.entity.query.ProjPaymentQuery;
import cn.topevery.garden.entity.vo.ProjFilesVO;
import cn.topevery.garden.entity.vo.ProjPaymentMoneyVO;
import cn.topevery.garden.entity.vo.ProjPaymentVO;
import cn.topevery.garden.entity.vo.ProjSituationRecordMoneyVO;
import cn.topevery.garden.framework.base.BaseLogic;
import cn.topevery.garden.framework.Database;
import hw.topevery.framework.db.base.BaseEntityDao;
import hw.topevery.framework.db.entity.DataPager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 项目支付表
 *
 * @author code-generate
 * @date 2022-11-02
 */
@Service
public class ProjPaymentLogic extends BaseLogic<ProjPayment> {

    @Autowired
    ProjPaymentDao projPaymentDao;

    @Autowired
    ProjFilesLogic projFilesLogic;

    @Autowired
    ProjBasicInfoLogic projBasicInfoLogic;

    @Autowired
    ProjContractLogic projContractLogic;

    @Autowired
    ProjRequestFundsPlanLogic projRequestFundsPlanLogic;

    @Override
    public BaseEntityDao<ProjPayment, Integer> getDao() {
        return projPaymentDao;
    }

    public Boolean saveOrUpdateOrDelete(String userId, ProjPaymentCudDTO cudDto) {
        if (ObjectUtil.isEmpty(cudDto)) {
            throw new RuntimeException("传入的集合不能为空！");
        }
        Database.transactionScope(() -> {
            List<ProjPaymentDTO> dtoList = cudDto.getSaveAndUpdateProjPaymentList();
            if (CollUtil.isNotEmpty(dtoList)) {
                this.saveOrUpdate(userId, dtoList);
            }
            Integer[] deleteIds = cudDto.getDeleteIds();
            if (ObjectUtil.isNotEmpty(deleteIds)) {
                this.deleteBatchById(userId, deleteIds);
            }
        });
        return true;
    }

    public Boolean saveOrUpdate(String userId, List<ProjPaymentDTO> dtoList) {
        if (CollUtil.isEmpty(dtoList)) {
            throw new RuntimeException("传入的集合不能为空！");
        }
        // 校验数据
        for (ProjPaymentDTO dto : dtoList) {
            this.checkProjPaymentData(dto);
        }
        Database.transactionScope(() -> {
            // 新增 修改
            for (ProjPaymentDTO dto : dtoList) {
                ProjPayment projPayment = new ProjPayment();
                BeanUtil.copyProperties(dto, projPayment);

                // 保存数据
                this.projPaymentDao.saveOrUpdate(userId, projPayment);

                // 更新请款表
                projRequestFundsPlanLogic.updatePaymentMoneyByReqFundsId(projPayment.getProjId(), projPayment.getReqFundsId());

                // 更新合同表 TODO


                //  保存附件
                if (ObjectUtil.isNotEmpty(dto.getFiles())) {
                    List<ProjFiles> files = dto.getFiles().stream().filter(i -> ObjectUtil.isEmpty(i.getId())).collect(Collectors.toList());
                    files.stream().forEach(i -> {
                        i.setProjId(dto.getProjId());
                        i.setProjStageId(projPayment.getPaymentId()); // 支付ID
                    });
                    if (CollUtil.isNotEmpty(files)) {
                        projFilesLogic.insert(userId, files);
                    }
                }
                //  删除附件
                if (ObjectUtil.isNotEmpty(dto.getDeleteFileIds())) {
                    projFilesLogic.delete(userId, dto.getDeleteFileIds());
                }
            }
        });
        return true;
    }

    /**
     * 根据自增id批量删除
     *
     * @param ids
     */
    public void deleteBatchById(String userId,Integer[] ids) {
        Database.transactionScope(() -> {
            // 根据ID查询招标信息
            ProjPaymentQuery query = new ProjPaymentQuery();
            query.setIds(ids);
            List<ProjPaymentVO> paymentVOList = this.projPaymentDao.list(query);
            if (CollUtil.isEmpty(paymentVOList)) {
                return;
            }
            List<String> paymentIds = paymentVOList.stream().map(paymentVO -> paymentVO.getPaymentId()).collect(Collectors.toList());


            projPaymentDao.delete(userId, ids);

            // 删除对应附件
            projFilesLogic.updateFilesByProjStageIds(paymentIds, null, userId);
        });
    }

    private void checkProjPaymentData(ProjPaymentDTO dto) {
        if (ObjectUtil.isEmpty(dto)) {
            throw new RuntimeException("传入的对象不能为空！");
        }
        if (ObjectUtil.isEmpty(dto.getProjId())) {
            throw new RuntimeException("项目ID不能为空！");
        }
        if (ObjectUtil.isEmpty(dto.getContractId())) {
            throw new RuntimeException("合同ID不能为空！");
        }
        if (ObjectUtil.isEmpty(dto.getReqFundsId())) {
            throw new RuntimeException("请款ID不能为空！");
        }
        if (ObjectUtil.isEmpty(dto.getPaymentMoney())) {
            throw new RuntimeException("支付金额不能为空！");
        }
        if (ObjectUtil.isEmpty(dto.getPaymentTime())) {
            throw new RuntimeException("支付时间不能为空！");
        }
        // 当不为空时为修改
        if (ObjectUtil.isNotEmpty(dto.getPaymentId())) {
            // 根据项目招标ID查询信息的有效性
            ProjPayment projPayment = this.getEntityById(dto.getPaymentId());
            if (ObjectUtil.isEmpty(projPayment)) {
                throw new RuntimeException("该支付信息在系统不存在，请检查或刷新数据！");
            }
            dto.setId(projPayment.getId());
        } else {
            dto.setPaymentId(UUID.randomUUID().toString());
        }

        // 校验附件
        this.projFilesLogic.checkFilesAndSetStageId(dto.getFiles(), dto.getPaymentId());

        // 检查项目ID
        ProjBasicInfo projBasicInfo = projBasicInfoLogic.getByProjId(dto.getProjId());
        if (ObjectUtil.isEmpty(projBasicInfo)) {
            throw new RuntimeException("该项目不存在，请检查!");
        }

        // 校验合同
        ProjContract projContract = projContractLogic.getEntityByGuidId(dto.getContractId());
        if (ObjectUtil.isEmpty(projContract)) {
            throw new RuntimeException("该合同不存在，请重新选择!");
        }
        if (projContract.getDbStatus()) {
            throw new RuntimeException("该合同无效，请重新选择!");
        }
        // 校验请款计划
        ProjRequestFundsPlan projRequestFundsPlan = projRequestFundsPlanLogic.getEntityByGuidId(dto.getReqFundsId());
        if (ObjectUtil.isEmpty(projRequestFundsPlan)) {
            throw new RuntimeException("该合同不存在，请重新选择!");
        }
        if (projRequestFundsPlan.getDbStatus()) {
            throw new RuntimeException("该请款计划无效，请重新选择!");
        }
    }

    public ProjPayment getEntityById(String paymentId) {
        if (ObjectUtil.isEmpty(paymentId)) {
            throw new RuntimeException("传入的支付ID不能为空");
        }
        return this.projPaymentDao.getEntityByGuidId(paymentId);
    }

    /**
     * 获取列表
     *
     * @param query
     * @return
     */
    public List<ProjPaymentVO> list(ProjPaymentQuery query) {
        List<ProjPaymentVO> list = projPaymentDao.list(query);
        // 当传入的项目ID不为空时，查询标段附件信息
        if (ObjectUtil.isNotEmpty(query.getProjId())) {
            if (CollUtil.isNotEmpty(list)) {
                // 获取项目支付文件
                List<ProjFilesVO> filesList = projFilesLogic.listByProjIdAndStageTypeCode(query.getProjId(), StringConstant.ProjStageFileCode.ProjPayment);
                if (CollUtil.isNotEmpty(filesList)) {
                    for (ProjPaymentVO projPaymentVO : list) {
                        List<ProjFilesVO> filesVOs = filesList.stream().filter(files -> ObjectUtil.isNotEmpty(files.getProjStageId()) && files.getProjStageId().equals(projPaymentVO.getPaymentId())).collect(Collectors.toList());
                        projPaymentVO.setFiles(filesVOs);
                    }
                }
            }
        }
        return list;
    }

    /**
     * 获取分页列表
     *
     * @param query
     * @return
     */
    public DataPager<ProjPaymentVO> listPage(ProjPaymentQuery query) {
        return projPaymentDao.listPage(query);
    }

    /**
     * 新增
     *
     * @param userId
     * @param dto
     */
    public void save(String userId, ProjPaymentDTO dto) {
        ProjPaymentQuery query = new ProjPaymentQuery();
        query.setProjId(dto.getProjId());
        query.setContractId(dto.getContractId());
        List<ProjPaymentVO> list = projPaymentDao.list(query);

        dto.setPaymentId(UUID.randomUUID().toString());
        dto.setPaymentCount(list.size() + 1);

        insert(userId, dto);
    }

    public ProjPaymentMoneyVO getPaymentMoney(ProjMoneyDTO moneyDTO) {
        if (ObjectUtil.isEmpty(moneyDTO)) {
            throw new RuntimeException("传入的对象不能为空！");
        }
        return this.projPaymentDao.getPaymentMoney(moneyDTO);
    }
}
